package project.tool4nat.server.handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import project.tool4nat.common.ChannelManager;
import project.tool4nat.common.Constants;
import project.tool4nat.common.DataPack;

public class CallerHandler extends SimpleChannelInboundHandler<ByteBuf> {

    private final static Logger logger = LoggerFactory.getLogger(CallerHandler.class);

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        logger.info("hashcode={}", this.hashCode());
//        logger.info("channel hashcode={}", ctx.channel().hashCode());
        if (ctx.channel().hasAttr(Constants.CID_KEY)) {
            logger.info("active start cid={}", ctx.channel().attr(Constants.CID_KEY).get());
        } else {
            logger.info("active start cid=null");
        }
        long cid = ChannelManager.newCid();
        logger.info("caller channel active, cid={}", cid);
        ctx.channel().attr(Constants.CID_KEY).set(cid);
        ChannelManager.addCaller(cid, ctx.channel());
        logger.info("active end cid={}", ctx.channel().attr(Constants.CID_KEY).get());
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//        logger.info("channel hashcode={}", ctx.channel().hashCode());
        long cid = ctx.channel().attr(Constants.CID_KEY).get();
        logger.info("caller channel inactive, cid={}", cid);
        ChannelManager.removeCaller(cid);
        super.channelInactive(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        long cid = ctx.channel().attr(Constants.CID_KEY).get();
        byte[] data = new byte[msg.readableBytes()];
        msg.readBytes(data);
        logger.info("receive msg from caller, cid={}\r\n{}", cid, new String());
        DataPack dataPack = new DataPack();

        dataPack.setCid(cid);
        dataPack.setData(data);
        Channel tunnel = ChannelManager.getProxyTunnel();
        if (tunnel != null) {
            tunnel.writeAndFlush(dataPack);
        }
    }
}
